package com.nemodynamic.cattivial.facebook;

import com.nemodynamic.cattivial.utils.DLog;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;

import android.os.Bundle;

import com.facebook.FacebookRequestError;
import com.facebook.HttpMethod;
import com.facebook.Request;
import com.facebook.Request.GraphUserListCallback;
import com.facebook.RequestAsyncTask;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.Request.Callback;
import com.facebook.Session.StatusCallback;
import com.facebook.SessionState;
import com.facebook.model.GraphUser;
import com.nemodynamic.cattivial.facebook.FacebookPostButton.OnFBPostListener;

public class FacebookUtils {
	public static final int UNLIMTED_ITEMS = -1;
	private static final String TAG = "FacebookUtils";
	private static boolean pendingPublishReauthorization = false;
	private static HashMap<OnFBSessionChangeListener, StatusCallback> listenerCallbackMap;

	public static void publishStory(final Activity ctx, String[] attr) {
		publishStory(ctx, attr, null);
	}

	public static void publishStory(final Activity ctx, String[] attr, final OnFBPostListener onFBPostListener) {
		Session session = Session.getActiveSession();
		if (session == null) {
			session = Session.openActiveSessionFromCache(ctx);
		}
		if (session != null && session.isOpened()) {

			Bundle postParams = new Bundle();
			if (attr[0] != null)
				postParams.putString("name", attr[0]);
			if (attr[1] != null)
				postParams.putString("caption", attr[1]);
			if (attr[2] != null)
				postParams.putString("description", attr[2]);
			if (attr[3] != null)
				postParams.putString("link", attr[3]);
			if (attr[4] != null)
				postParams.putString("picture", attr[4]);

			if (onFBPostListener != null) {
				if (ctx != null) {
					ctx.runOnUiThread(new Runnable() {
						@Override
						public void run() {
							try {
								onFBPostListener.onFBPosting();
							} catch (Exception e) {
								DLog.e(TAG, e.getMessage());
							}
						}
					});
				}
			}

			Request.Callback callback = new Request.Callback() {
				public void onCompleted(Response response) {
					String postId = "";
					try {
						JSONObject graphResponse = response.getGraphObject().getInnerJSONObject();
						postId = graphResponse.getString("id");
					} catch (final JSONException e) {
						if (onFBPostListener != null) {
							if (ctx != null) {
								ctx.runOnUiThread(new Runnable() {
									@Override
									public void run() {
										try {
											onFBPostListener.onFBPostedError(new FacebookRequestError(10, "ERROR", e.getMessage()));
										} catch (Exception e) {
											DLog.e(TAG, e.getMessage());
										}
									}
								});
							}
						}
						DLog.e(TAG, "JSON error " + e.getMessage());
					} catch (final Exception e) {
						if (onFBPostListener != null) {
							if (ctx != null) {
								ctx.runOnUiThread(new Runnable() {
									@Override
									public void run() {
										try {
											onFBPostListener.onFBPostedError(new FacebookRequestError(10, "UNAUTHORIZED", e.getMessage()));
										} catch (Exception e) {
											DLog.e(TAG, e.getMessage());
										}
									}
								});
							}

						}
						DLog.e(TAG, "JSON error " + e.getMessage());
					}
					final FacebookRequestError error = response.getError();
					if (error != null) {
						if (onFBPostListener != null) {
							if (ctx != null) {
								ctx.runOnUiThread(new Runnable() {
									@Override
									public void run() {
										try {
											onFBPostListener.onFBPostedError(error);
										} catch (Exception e) {
											DLog.e(TAG, e.getMessage());
										}
									}
								});
							}
						}

					} else {
						final String id = postId;
						if (onFBPostListener != null) {
							if (ctx != null) {
								ctx.runOnUiThread(new Runnable() {
									@Override
									public void run() {
										try {
											onFBPostListener.onFBPostedSuccess(id);
										} catch (Exception e) {
											DLog.e(TAG, e.getMessage());
										}
									}
								});
							}
						}
					}
				}
			};

			Request request = new Request(session, "me/feed", postParams, HttpMethod.POST, callback);

			RequestAsyncTask task = new RequestAsyncTask(request);
			task.execute();
		} else {
			onFBPostListener.onFBnoLog();
		}

	}

	public static boolean isPendingPublishReauthorization() {
		return pendingPublishReauthorization;
	}

	public static void setPendingPublishReauthorization(boolean pendingPublishReauthorization) {
		FacebookUtils.pendingPublishReauthorization = pendingPublishReauthorization;
	}

	public static void addOnChangeSessionListener(final OnFBSessionChangeListener listener, final Activity activity) {
		if (listener != null) {
			Session session = Session.getActiveSession();
			if (session == null) {
				session = Session.openActiveSessionFromCache(activity);
				DLog.i(TAG, "Sessione" + session + "recuperata");
			}

			if (listenerCallbackMap == null) {
				DLog.i(TAG, "Listener Map created");
				listenerCallbackMap = new HashMap<FacebookUtils.OnFBSessionChangeListener, Session.StatusCallback>();
			}

			if (session != null) {
				if (listenerCallbackMap.containsKey(listener)) {
					DLog.i(TAG, "Listener already present to be refreshed");
					session.removeCallback(listenerCallbackMap.get(listener));// To solve fragment problem
					listenerCallbackMap.remove(listener);
				}

				StatusCallback newSessionCallBack = new StatusCallback() {

					@Override
					public void call(Session session, SessionState state, Exception exception) {
						if (state.equals(SessionState.OPENED_TOKEN_UPDATED)) {
							DLog.i(TAG, "OPENED_TOKEN_UPDATED");
							try {
								activity.runOnUiThread(new Runnable() {
									@Override
									public void run() {
										if (activity != null) {
											try {
												listener.onFBOpenedSessionTokenUpdated();
											} catch (Exception e) {
												DLog.e(TAG, e.getMessage());
											}
										}
									}
								});
							} catch (Exception e) {
								DLog.e(TAG, e.getMessage());
							}
							pendingPublishReauthorization = false;
						} else if (state.equals(SessionState.CREATED)) {
							DLog.i(TAG, "CREATED");
							try {
								activity.runOnUiThread(new Runnable() {
									@Override
									public void run() {
										if (activity != null) {
											try {
												listener.onFBCreatedSession();
											} catch (Exception e) {
												DLog.e(TAG, e.getMessage());
											}
										}
									}
								});
							} catch (Exception e) {
								DLog.e(TAG, e.getMessage());
							}
						} else if (state.equals(SessionState.CREATED_TOKEN_LOADED)) {
							try {
								DLog.i(TAG, "CREATED_TOKEN_LOADED");
								activity.runOnUiThread(new Runnable() {
									@Override
									public void run() {
										if (activity != null) {
											try {
												listener.onFBCreatedSessionTockenLoaded();
											} catch (Exception e) {
												DLog.e(TAG, e.getMessage());
											}
										}
									}
								});
							} catch (Exception e) {
								DLog.e(TAG, e.getMessage());
							}
						} else if (state.equals(SessionState.OPENED)) {
							try {
								DLog.i(TAG, "OPENED");
								activity.runOnUiThread(new Runnable() {
									@Override
									public void run() {
										if (activity != null) {
											try {
												listener.onFBOpenedSession();
											} catch (Exception e) {
												DLog.e(TAG, e.getMessage());
											}
										}
									}
								});

							} catch (Exception e) {
								DLog.e(TAG, e.getMessage());
							}
						} else if (state.equals(SessionState.CLOSED_LOGIN_FAILED)) {
							try {
								DLog.i(TAG, "CLOSED_LOGIN_FAILED");
								activity.runOnUiThread(new Runnable() {
									@Override
									public void run() {
										if (activity != null) {
											try {
												listener.onFBClosedSessionLogInFailed();
											} catch (Exception e) {
												DLog.e(TAG, e.getMessage());
											}
										}
									}
								});
							} catch (Exception e) {
								DLog.e(TAG, e.getMessage());
							}
						} else if (state.equals(SessionState.CLOSED)) {
							DLog.i(TAG, "CLOSED");
							try {
								activity.runOnUiThread(new Runnable() {
									@Override
									public void run() {
										if (activity != null) {
											try {
												listener.onFBClosedSession();
											} catch (Exception e) {
												DLog.e(TAG, e.getMessage());
											}
										}
									}
								});
							} catch (Exception e) {
								DLog.e(TAG, e.getMessage());
							}
						}
					}
				};
				session.addCallback(newSessionCallBack);
				listenerCallbackMap.put(listener, newSessionCallBack);
				DLog.i(TAG, "Added Listener" + newSessionCallBack);
			}
		}
	}

	public static void removeOnChangeSessionListener(OnFBSessionChangeListener listener) {
		// if (listenerCallbackMap != null) {
		// Session session = Session.getActiveSession();
		// if (session != null) {
		// StatusCallback callback = listenerCallbackMap.get(listener);
		// if (callback != null) {
		// session.removeCallback(callback);
		// DLog.i(TAG, "Removed Listener" + callback);
		// }
		// listenerCallbackMap.remove(listener);
		// }
		// }
	}

	public interface OnFBSessionChangeListener {
		public void onFBCreatedSession();

		public void onFBCreatedSessionTockenLoaded();

		public void onFBOpeningSession();

		public void onFBOpenedSession();

		public void onFBOpenedSessionTokenUpdated();

		public void onFBClosedSessionLogInFailed();

		public void onFBClosedSession();
	}

	public static boolean isSessionOpened(Context context) {
		Session session = Session.getActiveSession();
		if (session != null) {
			return session.isOpened();
		} else {
			session = Session.openActiveSessionFromCache(context);
			if (session != null) {
				return session.isOpened();
			}
		}
		return false;
	}
	public static Session isSession(Context context) {
		Session session = Session.getActiveSession();
		if (session != null) {
			return session;
		} else {
			session = Session.openActiveSessionFromCache(context);
			if (session != null) {
				return session;
			}
		}
		return null;
	}
	public final static ArrayList<FacebookFriendItem> getFamily(Context ctx, int maxItems) {
		ArrayList<FacebookFriendItem> familyItems = new ArrayList<FacebookFriendItem>();
		Session activeSession = Session.getActiveSession();
		System.out.println(activeSession);
		if (activeSession == null) {
			activeSession = Session.openActiveSessionFromCache(ctx);
		}
		if (activeSession != null) {
			if (activeSession.getState().isOpened()) {
				Request familyRequest = Request.newGraphPathRequest(activeSession, "me/family", new Callback() {

					@Override
					public void onCompleted(Response response) {
						DLog.i(response.toString());
					}

				});
				Response response = familyRequest.executeAndWait();
				JSONObject json_obj;
				try {

					json_obj = response.getGraphObject().getInnerJSONObject();
					System.out.println(json_obj);
					JSONArray json_obj_data_array = json_obj.getJSONArray("data");
					if (maxItems == UNLIMTED_ITEMS) {
						maxItems = json_obj_data_array.length();
					}
					for (int i = 0; i < (json_obj_data_array.length()) && i < maxItems; i++) {
						try {
							JSONObject json_obj_inner = json_obj_data_array.getJSONObject(i);
							String relationship = json_obj_inner.getString("relationship");
							String id = json_obj_inner.getString("id");
							String name = json_obj_inner.getString("name");
							System.out.println(id + "," + relationship + "," + name);
							familyItems.add(new FacebookFriendItem(id, relationship, name));
						} catch (Exception e) {
							DLog.e(TAG, e.getMessage());
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return familyItems;
	}

	public final static ArrayList<FacebookFriendItem> getFriends(Context ctx, int maxItems) {
		ArrayList<FacebookFriendItem> familyItems = new ArrayList<FacebookFriendItem>();
		Session activeSession = Session.getActiveSession();
		System.out.println(activeSession);
		if (activeSession == null) {
			activeSession = Session.openActiveSessionFromCache(ctx);
		}
		if (activeSession != null) {
			if (activeSession.getState().isOpened()) {
				Request friendRequest = Request.newMyFriendsRequest(activeSession, 
			            new GraphUserListCallback(){
			                @Override
			                public void onCompleted(List<GraphUser> users,
			                        Response response) {
			                }
			        });
				Bundle params = new Bundle();
		        params.putString("fields", "id,name");
		        friendRequest.setParameters(params);
		        Response response= friendRequest.executeAndWait();
		    
				JSONObject json_obj;
				try {

					json_obj = response.getGraphObject().getInnerJSONObject();
					System.out.println(json_obj);
					JSONArray json_obj_data_array = json_obj.getJSONArray("data");
					if (maxItems == UNLIMTED_ITEMS) {
						maxItems = json_obj_data_array.length();
					}
					for (int i = 0; i < (json_obj_data_array.length()) && i < maxItems; i++) {
						try {
							JSONObject json_obj_inner = json_obj_data_array.getJSONObject(i);
							
							String id = json_obj_inner.getString("id");
							String name = json_obj_inner.getString("name");
							
							familyItems.add(new FacebookFriendItem(id, null, name));
						} catch (Exception e) {
							DLog.e(TAG, e.getMessage());
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
		        
			}
		}
		return familyItems;
	}
}
